#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QDebug>
#include <QFile>

#include <stdio.h>
#include <stdlib.h>

/*
 * 函数作用：收集调试信息,就是捕获所有的打印信息
参数：QtMsgType
    ＜QtGlobal＞：：QtDebugMsg    0   由qDebug（）函数生成的消息。
    ＜QtGlobal＞：：QtInfoMsg        4   由qInfo（）函数生成的消息。
    ＜QtGlobal＞：：QtWarningMsg 1   由qWarning（）函数生成的消息。
    ＜QtGlobal＞：：QtCriticalMsg    2   由qCritical（）函数生成的消息。
    ＜QtGlobal＞：：QtCatalogMsg   3  由qFatal（）函数生成的消息。
    ＜QtGlobal＞：：QtSystemMsg        问题关键消息
    context：上下文信息
    msg：打印信息

*/
void MainWindow::myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) {

    // 请注意，这里我们使用的是 "w" 模式，即写入模式。如果文件 "a.txt" 不存在，它将被创建。
    // 如果文件已经存在，它将被截断为空文件。如果您希望将输出追加到现有文件末尾，可以使用 "a" 模式。
    FILE *filePtr;
    filePtr = fopen("a.txt", "a"); // 打开文件 a.txt 以便进行写操作

    QByteArray localMsg = msg.toLocal8Bit();                      // 打印信息
    const char *file = context.file ? context.file : "context";  // 当前打印语句所在的相对路径名
    const char *function = context.function ? context.function : "func_context"; // 打印语句所在函数名
    switch (type) {
    case QtDebugMsg:
        if (filePtr != NULL) {
            fprintf(filePtr, "QtDebugMsg: localMsg = %s (file = %s: context.line = %u, function = %s)\n", localMsg.constData(), file, context.line, function);
            fclose(filePtr); // 关闭文件
        }
        break;
    case QtInfoMsg:
        if (filePtr != NULL) {
            fprintf(filePtr, "QtInfoMsg: localMsg = %s (file = %s: context.line = %u, function = %s)\n", localMsg.constData(), file, context.line, function);
            fclose(filePtr); // 关闭文件
        }
        break;
    case QtWarningMsg:
        if (filePtr != NULL) {
            fprintf(filePtr, "QtWarningMsg: localMsg = %s (file = %s: context.line = %u, function = %s)\n", localMsg.constData(), file, context.line, function);
            fclose(filePtr); // 关闭文件
        }
        break;
    case QtCriticalMsg:
        if (filePtr != NULL) {
            fprintf(filePtr, "QtCriticalMsg: localMsg = %s (file = %s: context.line = %u, function = %s)\n", localMsg.constData(), file, context.line, function);
            fclose(filePtr); // 关闭文件
        }
        break;
    case QtFatalMsg:
        if (filePtr != NULL) {
            fprintf(filePtr, "QtFatalMsg: localMsg = %s (file = %s: context.line = %u, function = %s)\n", localMsg.constData(), file, context.line, function);
            fclose(filePtr); // 关闭文件
        }
        break;
    default:
        break;
    }
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

     // QtMessageHandler qInstallMessageHandler(QtMessageHandler handler)
     qInstallMessageHandler(myMessageOutput);
}

MainWindow::~MainWindow()
{
    qDebug()<<"MainWindow::~MainWindow";

    // 若要还原消息处理程序，请调用(解释：关闭myMessageOutput这个静态函数的调用)
    qInstallMessageHandler(0);
    delete ui;
}

// qDebug(const char *message, ...)
void MainWindow::on_pb_QtDebugMsg_clicked()
{
    qDebug("my name is qDebug");
}

// 如果包含<QtDebug>，还可以使用更方便的语法：
//  qInfo() << "Brush:" << myQBrush << "Other value:" << i;
void MainWindow::on_pb_QtInfoMsg_clicked()
{
    qInfo("my name is qInfo");

}

void MainWindow::on_pb_QtInfoMsg_pressed()
{
    qInfo() << "qInfo";
}

// 要求只处理c小于等于200的数
static void warn(int c)
 {
     if (c > 200)
         qWarning("f: bad argument, c == %d", c);
 }
void MainWindow::on_pb_QtWarningMsg_clicked()
{
    warn(201);
}

static void load(const QString &fileName)
 {
    // 以const char*的形式返回fileName。这相当于fileName.toUtf8（）.constData（）。
     QFile file(fileName);
     if (!file.exists())
         qCritical("File '%s' does not exist!", qUtf8Printable(fileName));
 }
void MainWindow::on_pb_QtCriticalMsg_clicked()
{
    load("hahaha.txt");
}

// 不能除以零验证
static int divide(int a, int b)
 {
     if (b == 0)                                // program error
         qFatal("divide: Cannot divide by zero");
     return a / b;
 }
// 函数原型：qFatal(const char *message, ...)
void MainWindow::on_pb_QtFatalMsg_clicked()
{
   divide(1,0);  // 执行这个程序异常退出
}



// 打印日志文件
void MainWindow::on_pb_readFile_clicked()
{
    QFile file("a.txt");
    if (file.open(QIODevice::ReadOnly)) {
        ui->listWidget->addItems(QStringList(file.readAll()));
    }
}


